/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cn.ac.iie.di.ban.ycl.bk.e2p.ysyb.main;

import cn.ac.iie.di.ban.ycl.bk.e2p.ysyb.service.FJRThreadTask;
import cn.ac.iie.di.ban.ycl.bk.e2p.ysyb.tools.CompanyFolder;
import cn.ac.iie.di.ban.ycl.bk.e2p.ysyb.tools.PatternTools;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

/**
 *
 * @author wmr
 */
public class BanBkE2p {

//    private static Logger logger = Logger.getLogger(BanBkE2p.class);
    private static Logger logger = null;
    public static String localFilePathBase = null;
//    public static String localFilePath = null;
    public static String timeout = null;
    public static String alltimeout = null;
    public static String ffmpegPath = null;
    public static String confDir = null;
    public static String lcBasePath = null;
    public static int threadmax;
    public static int threadmin;
    public static BlockingQueue<String> threadList = new LinkedBlockingQueue<String>();//用来存放正在解析的json文件，读入后加入，结束后删除
//    static String logFilePath = BanBkE2p.class.getResource("/").getFile() + "log4j.properties";
//    static String locFilePath = BanBkE2p.class.getResource("/").getFile() + "localfile.properties";
    static {
        PropertyConfigurator.configure(ClassLoader.getSystemClassLoader().getResource("log4j.properties"));
        logger = Logger.getLogger(BanBkE2p.class);
    }

    public static void main(String[] args) {
//        BanBkE2p.confDir = args[0];
//        BanBkE2p.confDir = "E:/tu/maven/ban-bk-e2p/src/main/resources";
//        BanBkE2p.confDir = "/home/wmr/NetBeansProjects/Maven_project/ban-bk-e2p-ysyb/src/main/resources";

//        try {
////            PropertyConfigurator.configure("log4j.properties");
////            System.out.println("LOGFILE:"+);
//
//            String logFilePath = BanBkE2p.confDir + "/log4j.properties";
//            PropertyConfigurator.configure(logFilePath);
//        } catch (Exception ex) {
//            logger.error("read propertiesRootPath err!" + ex.getMessage(), ex);
//            return;
//        }
        boolean flag = true;
        Properties prop = new Properties();
        try {
//            InputStream in = new FileInputStream("localfile.properties");
//            String locFilePath = BanBkE2p.confDir + "/localfile.properties";
            String locFilePath = ClassLoader.getSystemClassLoader().getResource("localfile.properties").getFile();
            InputStream in = new FileInputStream(locFilePath);
            prop.load(in);
            in.close();
            //轮询json的目录
            BanBkE2p.localFilePathBase = prop.getProperty("localfilepath").trim();///home/bkftp/BK_DATA
            BanBkE2p.timeout = prop.getProperty("timeout").trim();
//            BanBkE2p.alltimeout = prop.getProperty("alltimeout").trim();
            //视频取帧的目录
            BanBkE2p.ffmpegPath = prop.getProperty("ffmpegPath").trim();
            //拷贝龙存的根目录
            BanBkE2p.lcBasePath = prop.getProperty("lcBasePath").trim();
            BanBkE2p.threadmax = Integer.parseInt(prop.getProperty("threadmax").trim());
            BanBkE2p.threadmin = Integer.parseInt(prop.getProperty("threadmin").trim());
            logger.info("localFilePathBase: " + localFilePathBase + " ---------- " + "timeout: " + timeout);
        } catch (Exception e) {
            flag = false;
            logger.error("localfile.properties file read fail! " + e.getMessage(), e);
        }

//        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2, 4, 3,
//                TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100),
//                new ThreadPoolExecutor.DiscardOldestPolicy());
        try {//死循环实现轮循目录。
            while (true) {
//                String[] lps = localFilePaths.split(";");
                traverseFolder(localFilePathBase);
                try {
                    logger.info("10" + " 分钟后，继续轮询目录。");
                    Thread.sleep(1 * 100000);
                } catch (InterruptedException ex) {
                    logger.error("SLEEP ERROR." + ex.getMessage(), ex);
                }
            }
        } catch (Exception ex) {
            logger.error("EXECUTE ERROR." + ex.getMessage(), ex);
        } finally {
            logger.info("成功停止。");
            logger.info("退出程序。");
        }
    }

    private static void execute(String localFilePath) {
        ///home/bkftp/BK_DATA/YOUKU/ToPlatForm/1_BK
        logger.info("获取任务目录：" + localFilePath + "/Ctrl");
        String nameSpace = localFilePath.substring(localFilePath.lastIndexOf("/") + 1, localFilePath.length());//1_bk
        String[] temNameSpace = nameSpace.split("_");
        String sourceFileType;
        if (temNameSpace.length == 2) {
            sourceFileType = nameSpace.split("_")[1];//BK
        } else {
            logger.error("nameSpace Directory structure error!!!");
            return;
        }
        String ctrlPath = localFilePath + "/Ctrl";
        File fileRoot = new File(ctrlPath);///home/bkftp/BK_DATA/YOUKU/ToPlatForm/1_BK/Ctrl
        //return 回到死循环。return之前设置为null，提示JVM可以进行垃圾回收了
        if (!fileRoot.isDirectory()) {//ctrlPath 错误的情况
            logger.fatal("**********************************************************");
            logger.fatal("获取任务目录：" + ctrlPath + " 不存在。");
            logger.fatal("**********************************************************");
            fileRoot = null;
            return;
        }
        String[] allFileList = fileRoot.list();//所有json文件名
        //没有sql文件返回
        if (allFileList.length < 1) {
            logger.info("获取任务目录下没有文件");
            return;
        }
        //判断是否为文件夹
        if (allFileList.length == 1) {
            File fileFlag = new File(ctrlPath + File.separator + allFileList[0]);
            if (fileFlag.isDirectory()) {//是文件夹跳过
                return;
            }
        }

        List<String> jsonNameList = new ArrayList<String>();
        List<String> okList = new ArrayList<String>();
        List<String> dwdList = new ArrayList<String>();
        List<String> otherdwdList = new ArrayList<String>();
        List<String> otherList = new ArrayList<String>();
        for (String f : allFileList) {
            if (PatternTools.matchStr("json", f)) {//判断是否为带json的文件
                if (f.contains("." + sourceFileType + ".dwd")) {
                    dwdList.add(f);
                } else if (f.endsWith(".ok")) {
                    okList.add(f);
                } else if (f.endsWith(".dwd")) {
                    otherdwdList.add(f);
                } else if (f.endsWith(".json")) {
                    jsonNameList.add(f);
                } else {
                    otherList.add(f);
                }
            }
        }

        //起线程池
        long begin = System.currentTimeMillis();
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(threadmin, threadmax, 3,
                TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(jsonNameList.size()),
                new ThreadPoolExecutor.DiscardOldestPolicy());
        //以json结尾的文件+.ok
        for (int i = 0; i < jsonNameList.size(); i++) {
            if (PatternTools.matchStr("json", jsonNameList.get(i))) {
                String tmpname = jsonNameList.get(i) + ".ok";
                for (int j = 0; j < okList.size(); j++) {
                    //判断与json与json.ok是否相等
                    if (tmpname.equals(okList.get(j))) {
                        boolean flag = false;
                        for (int k = 0; k < dwdList.size(); k++) {
                            String tmpdwdname = jsonNameList.get(i) + "." + sourceFileType + ".dwd";
                            //判断与json与json.BK.dwd是否相等
                            if (tmpdwdname.equals(dwdList.get(k))) {
                                flag = true;
                                break;
                            }
                        }
                        if (!flag) {
                            //判断是否已经开始运行
                            boolean alreadyExecute = false;
                            Iterator<String> itr = BanBkE2p.threadList.iterator();
                            while (itr.hasNext()) {
                                if (!itr.next().equals(jsonNameList.get(i))) {
                                    //如果threadList里的json不等于json文件名
                                } else {
                                      //如果threadList里的json等于json文件名
                                    alreadyExecute = true;
                                    break;
                                }
                            }
                            if (alreadyExecute) {
                                logger.info(jsonNameList.get(i) + "正在运行，跳过。");
                                continue;
                            } else {
                                //没有运行添加到队列中
                                BanBkE2p.threadList.add(jsonNameList.get(i));
                            }
                            threadPool.execute(new FJRThreadTask(jsonNameList.get(i), BanBkE2p.timeout, localFilePath));
//                            new FJRThreadTask(jsonNameList.get(i), BanBkE2p.timeout, localFilePath).run();
                        }

                    }
                }
            }
        }

        while (true) {//直至所有线程结束，才继续
            int activeThread = threadPool.getActiveCount();
            if (activeThread == 0) {
                break;
            } else {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException ex) {
                    logger.error(ex.getMessage(), ex);
                }
            }
        }
//        while (true) {//直至所有线程结束，才继续
//            int activeThread = threadPool.getActiveCount();
//            if (activeThread == 0) {
//                break;
//            } else {
//                try {
//                    long end = System.currentTimeMillis();
//                    long middle = (end - begin) / 1000;
//                    long tmpTimeout = Long.parseLong(alltimeout);
//                    if (middle < tmpTimeout) {
//                        logger.info(" runtime:" + middle + " timeout:" + alltimeout);
//                        Thread.sleep(3000);
//                    } else {
//                        logger.error(" upload is killed, because of timeout!");
//                        threadPool.shutdown();
//                        fileRoot = null;
//                        allFileList = null;
//                        echoRunning();
//                        return;
//                    }
//                    Thread.sleep(1000);
//                } catch (InterruptedException ex) {
//                    logger.error(" sleep error " + ex.getMessage(), ex);
//                }
//            }
//        }
        threadPool.shutdown();

        fileRoot = null;
        allFileList = null;
        echoRunning();
    }

    private static void echoRunning() {
        if (BanBkE2p.threadList.size() == 0) {
            logger.info("=============[" + BanBkE2p.threadList.size() + "]个过程正在运行。");
        } else {
            logger.info(">>>>>>>>>>>>>[" + BanBkE2p.threadList.size() + "]个过程正在运行。");
            Iterator<String> itr = BanBkE2p.threadList.iterator();
            StringBuffer sb = new StringBuffer();
            sb.append("[");
            while (itr.hasNext()) {
                sb.append(itr.next());
                sb.append(",");
            }
            sb.deleteCharAt(sb.length() - 1);
            sb.append("]");
            logger.info(">>>>>>>>>>>>>" + sb.toString());
            sb = null;
        }
    }
    
    
    //轮询/home/bkftp/BK_DATA 中各企业的*_BK文件夹
    public static void traverseFolder(String path) {
        ///home/bkftp/BK_DATA/YOUKU/ToPlatForm/1_BK/Ctrl
        File file = new File(path);
        if (file.exists()) {
            File[] files = file.listFiles();
            if (files.length == 0) {
                logger.info("文件夹是空的!");
                return;
            } else {
                //遍历企业目录
                for (File file2 : files) {
                    if (file2.isDirectory()) {
                        logger.info("文件夹:" + file2.getAbsolutePath());
                        String localPath = file2.getAbsolutePath();
                        if(localPath.contains("_BK")){
                            execute(localPath);
                        }else{
                            traverseFolder(file2.getAbsolutePath());
                        }
                        
                    } else {
                        logger.fatal(file2.getAbsolutePath() + " 不是任务目录 。");
                        continue;
                    }
                }
            }
        } else {
            logger.info(path + " 文件夹不存在!");
        }
    }
}
